`timescale 1ns / 100ps
module image_milter(
input clk,
input rst_p,
input [7:0]data_gray_i,
input data_valid_i,
//input [7:0]data_gray,
//input data_valid,
input data_hs,
input data_vs,
output [7:0]milter_image_data,
output milter_image_valid
    );

wire [7:0]shift_in;
wire [7:0]shift1;
wire [7:0]shift2;
reg data_valid;
reg [7:0]data_gray;

always@(posedge clk)begin
data_valid <= #1 data_valid_i;
data_gray <= data_gray_i;
end
assign shift_in =data_gray;
 shift_ram shift_ram1(
.clk(clk),
.shift_in(data_gray),
.data_valid(data_valid),
.shift1(shift1),
.shift2(shift2)
    );
 reg[7:0]row11;
 reg[7:0]row12;
 reg[7:0]row13; 
 reg[7:0]row21;
 reg[7:0]row22;
 reg[7:0]row23; 
  reg[7:0]row31;
 reg[7:0]row32;
 reg[7:0]row33; 
 
 always@(posedge clk or posedge rst_p)begin
 if(rst_p)begin
 row11 <=8'b0;
 row12 <=8'b0;
 row13 <=8'b0;
 row21 <=8'b0;
 row22 <=8'b0;
 row23 <=8'b0;
 row31 <=8'b0;
 row32 <=8'b0;
 row33 <=8'b0; 
 end
 else if(data_hs&&data_vs)begin
       if(data_valid)begin
       row11 <=shift_in;
       row12 <=row11;
       row13 <=row12;
       row21 <=shift1;
       row22 <=row21;
       row23 <=row22;
       row31 <=shift2;
       row32 <=row31;
       row33 <=row32;
                    end 
 end
 else begin
     row11<= 'd0;
    row12 <= 'd0;
    row13<= 'd0;

    row21 <= 'd0;
    row22 <= 'd0;
    row23 <= 'd0;

    row31 <= 'd0;
    row32 <= 'd0;
    row33 <= 'd0;
 end
 end

wire [7:0]line0_max;
wire [7:0]line0_mid;
wire [7:0]line0_min;
wire [7:0]line1_max;
wire [7:0]line1_mid;
wire [7:0]line1_min;
wire [7:0]line2_max;
wire [7:0]line2_mid;
wire [7:0]line2_min;
wire [7:0]max_max;
wire [7:0]max_mid;
wire [7:0]max_min;
wire [7:0]mid_max;
wire [7:0]mid_mid;
wire [7:0]mid_min;
wire [7:0]min_max;
wire [7:0]min_mid;
wire [7:0]min_min;
wire [7:0]matrix_mid;

reg data_valid_dly1;
reg data_valid_dly2;
reg data_valid_dly3;
reg data_valid_dly4;

 always@(posedge clk or posedge rst_p)begin
 if(rst_p)begin
 data_valid_dly1 <=1'b0;
 data_valid_dly2 <=1'b0;
 data_valid_dly3 <=1'b0; 
 data_valid_dly4 <=1'b0;
 end
 else begin
 data_valid_dly1 <=data_valid;
 data_valid_dly2 <=data_valid_dly1;
 data_valid_dly3 <=data_valid_dly2; 
 data_valid_dly4 <=data_valid_dly3;
 end
 end
 
 
sort sort1(
.clk(clk),
.rst_p(rst_p),
.data1(row11),
.data2(row12),
.data3(row13),
.data_valid(data_valid_dly1),
.max(line0_max),
.mid(line0_mid),
.min(line0_min),
.data_valid_o()
);

sort sort2(
.clk(clk),
.rst_p(rst_p),
.data1(row21),
.data2(row22),
.data3(row23),
.data_valid(data_valid_dly1),
.max(line1_max),
.mid(line1_mid),
.min(line1_min),
.data_valid_o()
);

sort sort3(
.clk(clk),
.rst_p(rst_p),
.data1(row31),
.data2(row32),
.data3(row33),
.data_valid(data_valid_dly1),
.max(line2_max),
.mid(line2_mid),
.min(line2_min),
.data_valid_o()
);

sort sort4(
.clk(clk),
.rst_p(rst_p),
.data1(line0_max),
.data2(line1_max),
.data3(line2_max),
.data_valid(data_valid_dly2),
.max(max_max),
.mid(max_mid),
.min(max_min),
.data_valid_o()
);

sort sort5(
.clk(clk),
.rst_p(rst_p),
.data1(line0_mid),
.data2(line1_mid),
.data3(line2_mid),
.data_valid(data_valid_dly2),
.max(mid_max),
.mid(mid_mid),
.min(mid_min),
.data_valid_o()
);

sort sort6(
.clk(clk),
.rst_p(rst_p),
.data1(line0_min),
.data2(line1_min),
.data3(line2_min),
.data_valid(data_valid_dly2),
.max(min_max),
.mid(min_mid),
.min(min_min),
.data_valid_o()
);
 
sort sort7(
.clk(clk),
.rst_p(rst_p),
.data1(max_min),
.data2(mid_mid),
.data3(min_max),
.data_valid(data_valid_dly3),
.max(),
.mid(matrix_mid),
.min(),
.data_valid_o()
); 
assign milter_image_data=matrix_mid;
assign milter_image_valid=data_valid_dly4;    
endmodule
